package com.eshipenet.shipnet.equipmentdatahub
import org.joda.time.DateTime
import play.api.libs.json._

import scala.util.Try

object EdgeChannelData {

  implicit val jodaDateTimeReads: Reads[DateTime] = Reads[DateTime] {
    case JsString(str) => JsSuccess(DateTime.parse(str))
    case JsNumber(ns) =>
      val ms = ns / (1000 * 1000)
      JsSuccess(new DateTime(ms.toLong))
    case other => JsError(s"invalid DateTime format: $other")
  }

  implicit val jodaDateTimeWrites: Writes[DateTime] = (o: DateTime) => JsString(o.toString())
//  implicit val format: Format[EdgeChannelData] = Json.format[EdgeChannelData]
  def apply(raw: JsValue): Try[EdgeChannelData] = Try {
    val id        = (raw \ "id").as[String]
    val timestamp = (raw \ "timestamp").as[Long]
    val value     = (raw \ "value").as[JsValue]
    EdgeChannelData(id, timestamp, value, raw)
  }
}

case class EdgeChannelData(id: String, timestampNS: Long, value: JsValue, raw: JsValue) {
  def toJson: JsValue = raw.as[JsObject] ++ Json.obj(
    "id"        -> id,
    "timestamp" -> timestampNS,
    "value"     -> value,
  )

  def coerceDataType(dataType: DataType): Try[EdgeChannelData] = dataType.fromJValue(value).map { v =>
    this.copy(value = v)
  }
}
